package com.gin.no_gay_alliance.adpter.base;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;

import com.gin.jackson.utils.ObjectUtils;
import com.gin.no_gay_alliance.R;
import com.gin.no_gay_alliance.activity.BaseBindingActivity;
import com.gin.no_gay_alliance.utils.MyHandler;
import com.gin.no_gay_alliance.utils.ReflectUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

/**
 * @author : ginstone
 * @version : v1.0.0
 * @since : 2023/8/24 10:04
 **/
public abstract class BaseBindingRecyclerViewAdapter<T extends ViewBinding, D> extends RecyclerView.Adapter<BaseBindingRecyclerViewAdapter.ViewHolder> {
    @NonNull
    protected final Context context;
    @NonNull
    protected List<D> data;

    protected MyHandler handler;

    public BaseBindingRecyclerViewAdapter(Context context) {
        this(context, new ArrayList<>());
    }

    public BaseBindingRecyclerViewAdapter(@NonNull Context context, @NonNull List<D> data) {
        this.context = context;
        this.data = data;
        this.handler = getHandler(context);
    }

    /**
     * 绑定数据
     *
     * @param holder
     * @param b        绑定对象
     * @param position 位置
     */
    protected abstract void onBindViewHolder(ViewHolder<T> holder, @NonNull T b, int position, D item);

    /**
     * 清空数据
     */
    public void clear() {
        data.clear();
    }

    /**
     * 构造binding对象
     *
     * @param inflater
     * @return T
     */
    @NonNull
    protected T buildBinding(LayoutInflater inflater) {
        try {
            ParameterizedType parameterizedType = ReflectUtils.findParameterizedType(getClass());
            if (parameterizedType != null) {
                Type type = parameterizedType.getActualTypeArguments()[0];
                if (type instanceof Class<?>) {
                    Class<?> clazz = ((Class<?>) type);
                    Method method = clazz.getMethod("inflate", LayoutInflater.class);
                    return (T) method.invoke(clazz, inflater);
                } else {
                    System.out.println("type = " + type);
                }
            }
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
        return null;
    }

    /**
     * @return 是否应用斑马纹配色
     */
    protected boolean useZebraStripe() {
        return true;
    }

    /**
     * 根布局的宽高设置会丢失，需要重新配置
     *
     * @return
     */
    protected ViewGroup.LayoutParams buildLayoutParamsForRoot() {
        return new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    @SuppressLint("NotifyDataSetChanged")
    public final void updateData(List<D> data) {
        this.data = ObjectUtils.isEmpty(data) ? new ArrayList<>() : data;
        notifyDataSetChanged();
    }

    /**
     * 添加数据到末尾
     *
     * @param items 数据
     */
    public final void pushData(Collection<D> items) {
        if (!ObjectUtils.isEmpty(items)) {
            int size = data.size();
            data.addAll(items);
            notifyItemRangeInserted(size, items.size());
        }
    }

    public final void insertData(D item, @IntRange(from = 0) int index) {
        data.add(index, item);
        notifyItemInserted(index);
    }

    @NonNull
    @Override
    public final ViewHolder<T> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        T binding = buildBinding(inflater);
        binding.getRoot().setLayoutParams(buildLayoutParamsForRoot());
        return new ViewHolder<>(binding);
    }

    @Override
    public final void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        //斑马配色
        if (useZebraStripe()) {
            TypedValue typedValue = new TypedValue();
            int attr = position % 2 == 0 ? R.attr.colorRowLight : R.attr.colorRowDark;
            context.getTheme().resolveAttribute(attr, typedValue, true);
            holder.binding.getRoot().setBackgroundColor(typedValue.data);
        }
        onBindViewHolder(holder, (T) holder.binding, position, data.get(position));
    }

    @Override
    public int getItemCount() {
        return data == null ? 0 : data.size();
    }

    public static void setVisibleOrGone(boolean condition, View... views) {
        if (views != null) {
            for (View view : views) {
                view.setVisibility(condition ? View.VISIBLE : View.GONE);
            }
        }
    }

    public static void setVisibleOrInvisible(boolean condition, View... views) {
        if (views != null) {
            for (View view : views) {
                view.setVisibility(condition ? View.VISIBLE : View.INVISIBLE);
            }
        }
    }

    public static void setTag(Object tag, View... views) {
        if (views != null) {
            for (View view : views) {
                view.setTag(tag);
            }
        }
    }

    private static MyHandler getHandler(Context context) {
        if (context instanceof BaseBindingActivity<?>) {
            return ((BaseBindingActivity<?>) context).getHandler();
        }
        return null;
    }

    @NonNull
    public List<D> getData() {
        return data;
    }

    public int getSize() {
        if (ObjectUtils.isEmpty(data)) {
            return 0;
        }
        return data.size();
    }

    public void setHandler(MyHandler handler) {
        this.handler = handler;
    }

    public static class ViewHolder<T extends ViewBinding> extends RecyclerView.ViewHolder {
        public T binding;
        /**
         * 用来保存额外对象
         */
        public HashMap<String, Object> objectMap = new HashMap<>();

        public ViewHolder(@NonNull T binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }
}